package juc.blockqueue.linkedblockdeque;

/**
 * @ClassName SlidingWindowProcessor
 * @PackageName juc.blockqueue.linkedblockdeque
 * @projectName myThread
 * @Description 3. 滑动窗口数据处理
 * @Author games
 * @Date 2025/9/4 下午3:24
 * @Version 1.0
 */

import java.util.concurrent.LinkedBlockingDeque;

class SlidingWindowProcessor {
    private final LinkedBlockingDeque<Integer> window;
    private final int windowSize;

    /**
     * 滑动窗口处理器类，用于维护一个固定大小的数据窗口，并计算窗口内数据的平均值
     */
    public SlidingWindowProcessor(int windowSize) {
        // 初始化窗口大小
        this.windowSize = windowSize;
        // 创建一个指定容量的阻塞双端队列作为窗口
        this.window = new LinkedBlockingDeque<>(windowSize);
    }

    /**
     * 向滑动窗口中添加新数据
     *
     * @param data 要添加的数据
     * @throws InterruptedException 如果在等待添加数据时被中断
     */
    public void addData(int data) throws InterruptedException {
        // 当窗口已满时，移除最旧的数据
        if (window.size() >= windowSize) {
            // 移除最旧的数据（从头部）
            Integer removed = window.pollFirst();
            if (removed != null) {
                System.out.println("移除旧数据: " + removed);
            }
        }
        // 添加新数据（到尾部）
        window.putLast(data);
        System.out.println("添加新数据: " + data);
        System.out.println("当前窗口: " + window);
    }

    /**
     * 计算并返回窗口内所有数据的平均值
     *
     * @return 窗内数据的平均值，如果窗口为空则返回0.0
     */
    public double getAverage() {
        // 使用Java 8 Stream API计算平均值
        return window.stream().mapToInt(Integer::intValue).average().orElse(0.0);
    }

    /**
     * 主方法，用于演示滑动窗口处理器的功能
     *
     * @param args 命令行参数（未使用）
     * @throws InterruptedException 如果在执行过程中被中断
     */
    public static void main(String[] args) throws InterruptedException {
        // 创建一个大小为5的滑动窗口处理器
        SlidingWindowProcessor processor = new SlidingWindowProcessor(5);

        // 模拟数据流入，添加10个数据点
        for (int i = 1; i <= 10; i++) {
            // 添加数据（i * 10）
            processor.addData(i * 10);
            // 打印当前窗口内数据的平均值
            System.out.println("当前平均值: " + processor.getAverage());
            System.out.println("-------------------");
            // 暂停1秒，便于观察输出
            Thread.sleep(1000);
        }
    }
}
